<template>
  <el-dialog :close-on-click-modal='false' v-drag title="上传升级文件" :v-show="dialogVisible" :visible.sync="dialogVisible" width="800px" top="5%" @close='closeSelect'>
    <uploader ref="uploader" :options="options" :autoStart="false" :singleFile='true' :file-status-text="fileStatusText" @file-added="onFileAdded" @file-success="onFileSuccess" @file-error="onFileError" @file-progress="onFileProgress" @file-removed='removeFile' class="uploader-example">
      <uploader-unsupport></uploader-unsupport>
      <uploader-btn :single='true' class="uploaderSystemFileButton" v-if="uploadShow">选择文件</uploader-btn>
      <!-- uploader-list可自定义样式 -->
      <!-- <uploader-list></uploader-list> -->
      <uploader-list>
        <div class="file-panel" :class="{ collapse: collapse }">
          <div class="file-title">
            <p class="file-list-title">文件列表</p>
            <div class="operate">
              <el-button type="text" @click="operate" :title="collapse ? '折叠' : '展开'">
                <i class="icon" :class="
                    collapse ? 'el-icon-caret-bottom' : 'el-icon-caret-top'
                  "></i>
              </el-button>
            </div>
          </div>

          <ul class="file-list" :class="
              collapse ? 'uploader-list-ul-show' : 'uploader-list-ul-hidden'
            ">
            <li v-for="file in uploadFileList" :key="file.id">
              <uploader-file :class="'file_' + file.id" ref="files" :file="file" :list="true" @remove='removeFile'></uploader-file>
            </li>
            <div class="no-file" v-if="!uploadFileList.length">
              <i class="icon icon-empty-file"></i> 暂无待上传文件
            </div>
          </ul>
        </div>
      </uploader-list>
    </uploader>
    <span slot="footer" class="dialog-footer">
      <el-button type="primary" @click="submit" v-if="uploadShow" class="addSubmit">确 定</el-button>
      <el-button @click="close" v-if="uploadShow" class="addClose">关 闭</el-button>
      <el-button type="danger" @click="stopUpload" v-if="!uploadShow" class="stopUpload">取 消</el-button>
      <el-button @click="closeShow" v-if="!uploadShow" class="addCloseShow">隐 藏</el-button>
    </span>
  </el-dialog>
</template>
<script>
import global from '@/global'
import { getSessionId } from '@/utils/auth'
import { uploadExist, updateCheck, uploadCancel, uploadMerge } from '@/api/system/update'
// const FILE_UPLOAD_ID_KEY = 'file_upload_id'
// 分片大小，20MB
const CHUNK_SIZE = 100 * 1024 * 1024
export default {
  data () {
    return {
      dialogVisible: false,
      options: {
        // 上传地址
        target: global.BASE_URL + '/update/upload',
        // 是否开启服务器分片校验。默认为 true
        testChunks: true,
        // 真正上传的时候使用的 HTTP 方法,默认 POST
        uploadMethod: 'post',
        // 分片大小
        chunkSize: CHUNK_SIZE,
        forceChunkSize: CHUNK_SIZE,
        // 并发上传数，默认为 3
        simultaneousUploads: 3,
        /**
         * 判断分片是否上传，秒传和断点续传基于此方法
         * 这里根据实际业务来 用来判断哪些片已经上传过了 不用再重复上传了 [这里可以用来写断点续传！！！]
         */
        headers: {
          'session_id': getSessionId()
        },
        checkChunkUploadedByResponse: (chunk, message) => {
          // message是后台返回
          let messageObj = JSON.parse(message)
          if (messageObj.status < 0) {
            this.$messages.error(messageObj.msg)
            return true
          }
          if (messageObj.info && messageObj.info.exists) {
            return (messageObj.info.exists || []).indexOf(chunk.offset + 1) >= 0
          }
          return false
          // 判断文件或分片是否已上传，已上传返回 true
          // 这里的 uploadedChunks 是后台返回]
          // return (dataObj.uploadedChunks || []).indexOf(chunk.offset + 1) >= 0
        },
        parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) {
          // 格式化时间
          return parsedTimeRemaining
            .replace(/\syears?/, '年')
            .replace(/\days?/, '天')
            .replace(/\shours?/, '小时')
            .replace(/\sminutes?/, '分钟')
            .replace(/\sseconds?/, '秒')
        }
      },
      // 修改上传状态
      fileStatusTextObj: {
        success: '上传成功',
        error: '上传错误',
        uploading: '正在上传',
        paused: '停止上传',
        waiting: '等待中'
      },
      uploadIdInfo: null,
      uploadFileList: [],
      fileChunkList: [],
      collapse: true,
      uploadShow: true,
      chunksNum: 0
    }
  },
  beforeDestroy () {
    if (this.uploadFileList[0] && !this.uploadShow) {
      this.uploadFileList[0].cancel()
    }
  },
  methods: {
    init () {
      this.dialogVisible = true
      let _that = this
      window.addEventListener('beforeunload', function (e) {
        if (_that.uploadFileList[0] && !_that.uploadShow) {
          _that.uploadShow = true
          uploadCancel({name: _that.uploadFileList[0].name, total_chunks: _that.uploadFileList[0].chunks.length})
        }
      }, true)
    },
    submit () {
      if (this.uploadFileList.length > 0 && this.$refs.files[0].status !== 'success') {
        this.uploadShow = false
        this.uploadFileList[0].resume()
      } else {
        this.$messages.error('请选择文件上传')
      }
    },
    onFileAdded (file, event) {
      uploadExist({name: file.name}).then(res => {
        this.chunksList = file.chunks.length
        this.uploadFileList = []
        this.uploadFileList.push(file)
      }).catch(e => {
        file.cancel()
      })
    },
    onFileSuccess (rootFile, file, response, chunk) {
      let messageObj = JSON.parse(response)
      uploadMerge({name: file.name, total_chunks: file.chunks.length}).then(response => {
        updateCheck({ name: file.name }).then(res => {
          this.uploadShow = true
          this.$messages.success(messageObj.msg)
          this.$parent.listData()
          this.close()
        }).catch(e => {
          this.uploadShow = true
        })
      })
    },
    onFileError (rootFile, file, message, chunk) {
      this.uploadShow = true
      this.$messages.error(message.msg)
    },
    onFileProgress (rootFile, file, chunk) {
      this.uploadShow = false
      // console.log(`当前进度：${Math.ceil(file._prevProgress * 100)}%`)
    },
    fileStatusText (status, response) {
      return this.fileStatusTextObj[status]
    },
    /**
     * 折叠、展开面板动态切换
     */
    operate () {
      if (this.collapse === false) {
        this.collapse = true
      } else {
        this.collapse = false
      }
    },
    removeFile () {
      if (!this.uploadShow) {
        uploadCancel({name: this.uploadFileList[0].name, total_chunks: this.uploadFileList[0].chunks.length}).then(res => {
          this.uploadShow = true
          this.$messages.error('已取消上传')
          this.uploadFileList = []
        }).catch(e => {
          this.uploadShow = true
          this.$messages.error('已取消上传')
          this.uploadFileList = []
        })
      } else {
        this.uploadShow = true
        this.uploadFileList = []
      }
    },
    closeShow () {
      this.dialogVisible = false
    },
    close () {
      if (!this.uploadShow) {
        uploadCancel({name: this.uploadFileList[0].name, total_chunks: this.uploadFileList[0].chunks.length}).then(res => {
          this.uploadFileList[0].cancel()
          this.uploadFileList = []
        })
      } else if (this.uploadFileList.length > 0) {
        this.uploadFileList[0].cancel()
        this.uploadFileList = []
      }
      this.dialogVisible = false
    },
    closeSelect () {
      if (this.uploadShow) {
        this.close()
      } else {
        this.closeShow()
      }
    },
    stopUpload () {
      if (this.uploadFileList.length > 0) {
        this.uploadFileList[0].cancel()
      }
      this.dialogVisible = false
      this.$nextTick(() => {
        this.uploadShow = true
      })
    }
  }
}
</script>
<style lang="less" scoped>
.uploader-example {
  width: 700px;
  margin: 0px auto 0;
  font-size: 12px;
  // box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
}
.uploader-example .uploader-btn {
  margin-right: 4px;
  margin-bottom: 4px;
}
.uploader-example .uploader-list {
  max-height: 440px;
  overflow: auto;
  overflow-x: hidden;
  overflow-y: auto;
}

#global-uploader {
  position: fixed;
  z-index: 20;
  right: 15px;
  bottom: 15px;
  width: 550px;
}

.file-panel {
  background-color: #fff;
  border: 1px solid #e2e2e2;
  border-radius: 7px 7px 0 0;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}

.file-title {
  display: flex;
  height: 60px;
  line-height: 30px;
  padding: 0 15px;
  border-bottom: 1px solid #ddd;
}

.file-title {
  background-color: #e7ecf2;
}

.uploader-file-meta {
  display: none !important;
}

.operate {
  flex: 1;
  text-align: right;
}

.file-list {
  position: relative;
  height: 49px;
  overflow-x: hidden;
  overflow-y: auto;
  background-color: #fff;
  padding: 0px;
  margin: 0 auto;
  transition: all 0.5s;
}

.uploader-file-size {
  width: 15% !important;
}

.uploader-file-status {
  width: 32.5% !important;
  text-align: center !important;
}

li {
  background-color: #fff;
  list-style-type: none;
}

.no-file {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 16px;
}

/* 隐藏上传按钮 */
.global-uploader-btn {
  display: none !important;
  clip: rect(0, 0, 0, 0);
  /* width: 100px;
  height: 50px; */
}

.file-list-title {
  /*line-height: 10px;*/
  font-size: 16px;
}

.uploader-file-name {
  width: 36% !important;
}

.uploader-file-actions {
  float: right !important;
}

.uploader-list-ul-hidden {
  height: 0px;

}
.uploaderSystemFileButton {
  color: #FFFFFF;
  background-color: #1890ff;
  border: 1px solid #1890ff;
  padding: 9px 15px;
  font-size: 12px;
  border-radius: 3px;
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: .1s;
  font-weight: 400;
}
.uploader-btn:hover {
  background: #46a6ff;
  border-color: #46a6ff;
  color: #FFFFFF;
}
</style>
